package com.qing.expert.common.aspect;

import cn.hutool.core.util.IdUtil;
import com.qing.expert.common.annotation.OperationLog;
import com.qing.expert.common.utils.IpUtil;
import com.qing.expert.common.utils.UserUtil;
import com.qing.expert.modules.admin.mapper.OperationLogMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Slf4j
@Aspect
@Component
public class OperationLogAspect {

    @Resource
    private OperationLogMapper operationLogMapper;

    @Resource
    private TransactionTemplate transactionTemplate;

    @Around("@annotation(operationLog)")
    public Object around(ProceedingJoinPoint point, OperationLog operationLog) throws Throwable {
        // 先执行方法
        Object result = point.proceed();

        try {
            log.info("开始记录操作日志");
            saveOperationLog(point, operationLog);
            log.info("操作日志记录完成");
        } catch (Exception e) {
            log.error("记录操作日志失败", e);
        }

        return result;
    }

    private void saveOperationLog(ProceedingJoinPoint point, OperationLog operationLog) {
        transactionTemplate.execute(status -> {
            try {
                ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                        .getRequestAttributes();
                if (attributes == null) {
                    log.error("获取请求上下文失败");
                    return null;
                }
                HttpServletRequest request = attributes.getRequest();

                // 获取当前登录用户ID
                String userId = UserUtil.getCurrentUserId();

                // 如果用户未登录,使用默认用户ID
                if (userId == null) {
                    userId = "system"; // 或其他默认值
                }

                log.info("当前操作用户: {}", userId);

                // 获取请求IP
                String ip = IpUtil.getIpAddr(request);

                // 构建日志对象
                com.qing.expert.modules.admin.entity.OperationLog operLog = new com.qing.expert.modules.admin.entity.OperationLog()
                        .setId(IdUtil.getSnowflakeNextIdStr())
                        .setUserId(userId) // 设置用户ID
                        .setAction(operationLog.action())
                        .setDetail(operationLog.detail())
                        .setIp(ip)
                        .setPath(request.getRequestURI())
                        .setMethod(request.getMethod());

                log.info("准备保存操作日志: {}", operLog.toString());

                // 保存日志
                operationLogMapper.insert(operLog);

                return null;
            } catch (Exception e) {
                log.error("保存操作日志失败", e);
                throw new RuntimeException("保存操作日志失败", e);
            }
        });
    }
}